﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Keepo.Models;
using AlbumDesigner.Models.Types;
using Infrastructure.Data;
using AlbumDesigner.Models.ViewModels;
using System.IO;
using System.Web.Script.Serialization;
using System.Diagnostics;
using Keepo.Models.Services;
using iTextSharp.text;
using iTextSharp.text.pdf;
using AlbumDesigner.Helpers;
using System.Drawing;
using System.Drawing.Imaging;
using AlbumDesigner.Models.Enums;
using Keepo.Helpers;

namespace AlbumDesigner.Controllers
{
    public class AlbumsController : Controller
    {
        [CheckPermission(section = "Albums")]
        public ActionResult Index()
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var viewModel = new AlbumsViewModel();

                //get list of statuses and lockStatuses
                viewModel.AlbumStatuses = new SelectList(repository.GetAll<AlbumStatus>(), "AlbumStatusId", "Title");
                viewModel.AlbumLockStatuses = new SelectList(repository.GetAll<AlbumLockStatus>(), "AlbumLockStatusId", "Title");

                //get the SalesMen list as SelectList
                viewModel.SalesMen = repository.Find<User>(m => m.UserPermissionId == (int)AlbumUsers.SalesMan).Select(m => new SelectListItem()
                {
                    Value = m.UserId.ToString(),
                    Text = m.FirstName + " " + m.LastName
                }).ToList();

                return View(viewModel);
            }
        }

        //[CheckPermission(section = "Albums")]
        public ActionResult All()
        {
            using (var db = new AlbumContext())
            {
                var viewModel = new AlbumsListViewModel();

                var albums = db.Albums.Select(x => new KeyValuePair<int, int>(1, 1)).ToList();

                return Json(albums, JsonRequestBehavior.AllowGet);
            }
        }

        [CheckPermission(section = "Albums")]
        [HttpPost]
        public ActionResult AlbumsList(string OrderBy, bool ShowOnlySalesManAlbums, bool ShowRemoved, int Page = 1)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //get all albums
                var albumsList = repository.GetAll<Album>();

                if (ShowRemoved == false)
                {
                    albumsList = albumsList.Where(m => m.IsRemoved == false);
                }

                //filter only albums that the current user is their Sales Man
                if (ShowOnlySalesManAlbums)
                {
                    var currentUser = UserHelper.CurrentUser();
                    if (currentUser != null)
                    {
                        var currentUserId = currentUser.UserId;
                        albumsList = albumsList.Where(m => m.SalesManId == currentUserId);
                    }
                }

                //order the albums list
                if (OrderBy == "Title")
                {
                    albumsList = albumsList.OrderBy(m => m.Title);
                }
                else if (OrderBy == "AlbumStatus")
                {
                    albumsList = albumsList.OrderBy(m => m.AlbumStatusId);
                }
                else if (OrderBy == "AlbumId")
                {
                    albumsList = albumsList.OrderBy(m => m.AlbumId);
                }
                else if (OrderBy == "DueDate")
                {
                    albumsList = albumsList.OrderBy(m => m.DueDate);
                }

                var albums = albumsList.Select(m => new AlbumData(m)).ToList();

                //add the Paging settings to the albums list
                int rowsPerPage = 10;
                int albumsCount = albums.Count();
                int startIndex = (Page - 1) * rowsPerPage;
                int pagesCount = albumsCount / rowsPerPage;
                if (albumsCount % rowsPerPage > 0)
                {
                    pagesCount++;
                }

                var albumsWithPaging = albums.Skip(startIndex).Take(rowsPerPage);

                return Json(new { Albums = albumsWithPaging, Pages = pagesCount });
            }
        }

        [HttpPost]
        public ActionResult IsOrderNumExists(string OrderNum)
        {
            //check if numeric value
            int orderNum = 0;
            if (int.TryParse(OrderNum, out orderNum) == false)
            {
                return Json(false);
            }

            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.First<Album>(m => m.OrderNum == orderNum && m.IsRemoved == false);

                //check if there is already album with the specified OrderNum
                if (album == null)
                {
                    return Json(false);
                }
                return Json(true);
            }
        }

        [CheckPermission(section = "Albums")]
        public ActionResult Add()
        {
            using (GenericRepository repository = new GenericRepository())
            {
                ViewBag.AlbumSectionTypesList = new SelectList(repository.Find<AlbumSectionType>(m => m.AlbumSectionTypeId != (int)AlbumSectionTypeEnum.Cover), "AlbumSectionTypeId", "Title");

                ViewBag.AlbumSizesList = new SelectList(repository.GetAll<AlbumSize>(), "AlbumSizeId", "Title");

                ViewBag.PapersList = new SelectList(repository.GetAll<Paper>(), "PaperId", "Title");

                //get list of Sales Men
                var salesMen = repository.Find<User>(m => m.UserPermissionId == (int)AlbumUsers.SalesMan).Select(m => new SelectListItem()
                {
                    Value = m.UserId.ToString(),
                    Text = m.FirstName + " " + m.LastName
                }).ToList();

                //if the current user is "Sales Man" user
                if (UserHelper.HasPermission((int)AlbumUsers.SalesMan))
                {
                    //select his item in the SelectList
                    var currentUser = UserHelper.CurrentUser();
                    salesMen.FirstOrDefault(m => m.Value == currentUser.UserId.ToString()).Selected = true;
                }

                ViewBag.SalesMen = salesMen;

                //get list of Photographers
                ViewBag.Photographers = repository.Find<User>(m => m.UserPermissionId == (int)AlbumUsers.Photographer).Select(m => new SelectListItem()
                {
                    Value = m.UserId.ToString(),
                    Text = m.FirstName + " " + m.LastName
                }).ToList();

                return View();
            }
        }

        [CheckPermission(section = "Albums")]
        [HttpPost]
        public ActionResult Add(AlbumData albumData, List<AlbumSectionData> sections, List<FilmingDay> filmingDays)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //create new Album object
                var album = new Album();
                album.Title = albumData.Title;
                album.NumOfCopies = albumData.NumOfCopies;
                album.NumOfPages = albumData.NumOfPages;
                album.OrderNum = albumData.OrderNum;
                album.AlbumSizeId = albumData.AlbumSizeId;
                album.PaperId = albumData.PaperId;
                album.DueDate = DateTime.Parse(albumData.DueDate);
                album.StudioNotes = albumData.StudioNotes;
                album.IsOneSided = albumData.IsOneSided;
                album.HasPhotographer = albumData.HasPhotographer;
                album.IncludeGraphics = albumData.IncludeGraphics;
                album.IntroPagesNumber = albumData.IntroPagesNumber;
                album.SalesManId = albumData.SalesManId;

                album.AlbumStatusId = 1; //default status
                album.AlbumLockStatusId = 1; //default lock status
                album.CreatedDate = DateTime.Now;

                album.FilmingDays = filmingDays;

                //create new User as the Editor of this Album (רכזת)
                int editorId = CreateUser(album.Title, "", albumData.EditorPassword, albumData.EditorEmail, albumData.EditorFirstName, albumData.EditorLastName, albumData.EditorPhone, albumData.EditorMobile);
                album.EditorId = editorId;

                /*Create Sections
                 ----------------*/

                album.AlbumSections = new List<AlbumSection>();

                //create Cover as the first AlbumSection
                var albumCover = new AlbumSection();
                albumCover.Title = "כריכה";
                albumCover.SectionIdx = 0;
                albumCover.PagesCount = 1;
                albumCover.AlbumSectionTypeId = 1; // כריכה
                albumCover.AlbumSectionStatusId = 1; //default status (לא מאושר)
                albumCover.AlbumSectionLockStatusId = 3; //default lock status (פתוח לעריכה)
                albumCover.EditorId = editorId;

                //add double AlbumPage for the new Cover
                albumCover.AlbumPages = new List<AlbumPage>();
                var coverPage = new AlbumPage();
                coverPage.SectionPageIdx = 0;
                coverPage.IsSingle = false;
                albumCover.AlbumPages.Add(coverPage);

                album.AlbumSections.Add(albumCover);

                //loop through all the defined Sections
                for (var i = 0; i < sections.Count; i++)
                {
                    //check that the pages number is valid (equal or great than 2, and even number)
                    if (sections[i].PagesCount >= 2 && sections[i].PagesCount % 2 == 0)
                    {
                        //create new AlbumSection object
                        var albumSection = CreateNewAlbumSection(album.Title, sections[i], i);

                        album.AlbumSections.Add(albumSection);
                    }
                }

                //add the album to DB
                repository.Add<Album>(album);
                repository.UnitOfWork.SaveChanges();

                return Json(new
                {
                    Url = Url.Action("Details", new { id = album.AlbumId }),
                    AlbumId = album.AlbumId
                });
            }
        }

        private AlbumSection CreateNewAlbumSection(string albumTitle, AlbumSectionData section, int index)
        {
            int sectionEditorId = CreateUser(albumTitle, section.SectionTitle, section.EditorPassword, section.EditorEmail, section.EditorFirstName, section.EditorLastName, section.EditorPhone, section.EditorMobile);

            //create new AlbumSection
            var albumSection = new AlbumSection();
            albumSection.Title = section.SectionTitle;
            albumSection.SectionIdx = index + 1;
            albumSection.PagesCount = section.PagesCount;
            albumSection.AlbumSectionTypeId = section.AlbumSectionTypeId;
            albumSection.AlbumSectionStatusId = 1; //default status (לא מאושר)
            albumSection.AlbumSectionLockStatusId = 3; //default lock status (פתוח לעריכה)
            albumSection.EditorId = sectionEditorId;

            /* Pages of Section
             ------------------*/

            albumSection.AlbumPages = new List<AlbumPage>();
            var pageIdx = 0;

            //create the first AlbumPage for this AlbumSection
            var firstAlbumPage = new AlbumPage();
            firstAlbumPage.SectionPageIdx = pageIdx;
            firstAlbumPage.IsSingle = true;
            firstAlbumPage.IsLeft = true;
            albumSection.AlbumPages.Add(firstAlbumPage);
            pageIdx++;

            //loop through the inner double pages that will be inserted to the section
            for (int j = 0; j < (section.PagesCount - 2) / 2; j++)
            {
                //create AlbumPage for this AlbumSection
                var albumPage = new AlbumPage();
                albumPage.SectionPageIdx = pageIdx;
                albumPage.IsSingle = false;
                albumSection.AlbumPages.Add(albumPage);
                pageIdx++;
            }

            //create the last AlbumPage for this AlbumSection
            var lastAlbumPage = new AlbumPage();
            lastAlbumPage.SectionPageIdx = pageIdx;
            lastAlbumPage.IsSingle = true;
            lastAlbumPage.IsLeft = false;
            albumSection.AlbumPages.Add(lastAlbumPage);

            return albumSection;
        }

        [HttpPost]
        public ActionResult Update(Album album)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var existAlbum = repository.GetByKey<Album>(album.AlbumId);
                var oldStatusId = existAlbum.AlbumStatusId;

                //if the lock status is being changed from "נעול" to "פתוח"
                if (existAlbum.AlbumLockStatusId == 1 && album.AlbumLockStatusId == 2)
                {
                    //change all sections lock status to "פתוח"
                    existAlbum.AlbumSections.ToList().ForEach(m => m.AlbumSectionLockStatusId = 3);
                }

                //update the album's details
                existAlbum.SalesManId = album.SalesManId;
                existAlbum.AlbumStatusId = album.AlbumStatusId;
                existAlbum.AlbumLockStatusId = album.AlbumLockStatusId;

                repository.UnitOfWork.SaveChanges();

                //send mail to notify the album editor
                SendMailForAlbumStatusChange(oldStatusId, existAlbum);

                return Json(new { Key = true, Value = "האלבום עודכן בהצלחה!" });
            }
        }

        [HttpPost]
        public ActionResult GeneratePassword()
        {
            var password = Guid.NewGuid().ToString().Substring(0, 5);

            return Json(password);
        }

        private int CreateUser(string albumTitle, string albumSectionTitle, string password, string email, string firstName, string lastName, string phone, string mobile)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //create User object as an editor
                var sectionEditor = new User() { Email = email, Password = password, FirstName = firstName, LastName = lastName, Phone = phone, Mobile = mobile };
                sectionEditor.Username = albumTitle;
                if (!string.IsNullOrEmpty(albumSectionTitle))
                {
                    sectionEditor.Username += "/" + albumSectionTitle;
                }
                sectionEditor.RegistrationDate = DateTime.Now;
                sectionEditor.UserPermissionId = (int)AlbumUsers.Client;
                sectionEditor.Activate = true;

                //add this user to the DB
                repository.Add<User>(sectionEditor);
                repository.UnitOfWork.SaveChanges();

                return sectionEditor.UserId;
            }
        }

        public ActionResult UploadImages(int? AlbumId, int? AlbumSectionId)
        {
            //redirect the user if he has no permission for this album
            if (!AlbumsLogic.canUserEdit(AlbumId.Value))
            {
                return View("NoPermission");
            }

            using (GenericRepository repository = new GenericRepository())
            {
                ViewBag.AlbumId = AlbumId;
                ViewBag.AlbumSectiosList = new SelectList(repository.Find<AlbumSection>(m => m.AlbumId == AlbumId), "AlbumSectionId", "Title");

                ViewBag.AlbumTitle = "";
                if (AlbumId != null)
                {
                    ViewBag.AlbumTitle = repository.GetByKey<Album>(AlbumId).Title;
                }

                return View();
            }
        }

        [HttpPost]
        public ActionResult UploadImage(int? albumId, int? albumSectionId, int chunk = 0, int chunks = 1)
        {
            //check if there is a file uploaded
            if (Request.Files[0] != null)
            {
                HttpPostedFileBase Filedata = (Request.Files[0] as HttpPostedFileBase);

                //insert the image to DB as AlbumImage
                var albumImage = new AlbumImage();
                albumImage.Title = Path.GetFileNameWithoutExtension(Filedata.FileName);

                //find the relevant Directory that these files will be saved into
                var directoryToSave = "";
                var url = "";

                //if there is no albumId or sectionId specified
                if (albumId == -1 && albumSectionId == -1)
                {
                    directoryToSave = Server.MapPath("~/resources/images");
                    url = "resources/images";
                }
                else
                {
                    if (albumId != null && albumId != -1)
                    {
                        url = "resources/albums/" + albumId + "/images";
                        directoryToSave = Server.MapPath("~/resources/albums/" + albumId + "/images");

                        albumImage.AlbumId = albumId.Value;
                    }
                    if (albumSectionId != null && albumSectionId != -1)
                    {
                        url = "resources/albums/" + albumId + "/sectionImages/" + albumSectionId;
                        directoryToSave = Server.MapPath("~/resources/albums/" + albumId + "/sectionImages/" + albumSectionId);

                        albumImage.AlbumSectionId = albumSectionId.Value;
                    }
                }

                if (!Directory.Exists(directoryToSave))
                {
                    Directory.CreateDirectory(directoryToSave);
                }

                if (chunk == 0)
                {
                    //generate file name for this image (guid string)
                    UploadHelper.CreateFileGuidInSession(Filedata.FileName);
                }

                //save the file (the file could be sent in chunks, if it's big)
                var guid = UploadHelper.GetFileGuidFromSession(Filedata.FileName);
                using (var fs = new FileStream(directoryToSave + "\\" + guid, chunk == 0 ? FileMode.Create : FileMode.Append))
                {
                    var buffer = new byte[Filedata.InputStream.Length];
                    Filedata.InputStream.Read(buffer, 0, buffer.Length);

                    fs.Write(buffer, 0, buffer.Length);
                }

                albumImage.URL = url + "/" + guid;

                //if this is the last chunk of the file
                if (chunk == chunks - 1)
                {
                    if (albumId != null)
                    {
                        try
                        {
                            ImageHelper.addDesignImage(albumImage);
                        }
                        catch (Exception e)
                        {
                            return Json(false);
                        }

                        UploadHelper.RemoveFileGuidFromSession(Filedata.FileName);
                    }
                }
            }

            return Json(true);
        }

        public ActionResult Details(int id)
        {
            //redirect the user if he has no permission for this album
            if (!AlbumsLogic.canUserEdit(id))
            {
                ViewBag.ShowAdminLink = true;
                return View("NoPermission");
            }

            using (GenericRepository repository = new GenericRepository())
            {
                var viewModel = new AlbumDetailsViewModel();

                JavaScriptSerializer jsSerializer = new JavaScriptSerializer();

                var album = repository.GetByKey<Album>(id);
                viewModel.Album = new AlbumData(album, true);

                // Only in details calculate the album size

                //serialize the AlbumSections list to JSON
                var albumSections = repository.Find<AlbumSection>(m => m.AlbumId == id).Select(m => new AlbumSectionData(m)).ToList();
                viewModel.AlbumSectionsJSON = jsSerializer.Serialize(albumSections);

                //serialize the FilmingDays list to JSON
                var filmingDays = repository.Find<FilmingDay>(m => m.AlbumId == id).Select(m => new FilmingDayData(m)).ToList();
                viewModel.FilmingDaysJSON = jsSerializer.Serialize(filmingDays);

                //get relevant lists for the details page
                viewModel.AlbumSizesList = new SelectList(repository.GetAll<AlbumSize>(), "AlbumSizeId", "Title");
                viewModel.PapersList = new SelectList(repository.GetAll<Paper>(), "PaperId", "Title");
                viewModel.AlbumStatusesList = new SelectList(repository.GetAll<AlbumStatus>(), "AlbumStatusId", "Title");
                viewModel.AlbumLockStatusesList = new SelectList(repository.GetAll<AlbumLockStatus>(), "AlbumLockStatusId", "Title");
                viewModel.AlbumPrintVersionStatusesList = new SelectList(repository.GetAll<AlbumPrintVersionStatus>(), "AlbumPrintVersionStatusId", "Title");

                //get the availiable AlbumSections statuses for the album editor
                var albumSectionsStatuses = repository.GetAll<AlbumSectionStatus>().ToList();
                viewModel.AlbumSectionStatusesList = new SelectList(albumSectionsStatuses, "AlbumSectionStatusId", "Title");

                //get the availiable AlbumSections LockStatuses for the album editor
                var albumSectionsLockStatuses = repository.GetAll<AlbumSectionLockStatus>().ToList();
                viewModel.AlbumSectionLockStatusesList = new SelectList(albumSectionsLockStatuses, "AlbumSectionLockStatusId", "Title");

                viewModel.AlbumSectionTypesList = new SelectList(repository.Find<AlbumSectionType>(m => m.AlbumSectionTypeId != (int)AlbumSectionTypeEnum.Cover), "AlbumSectionTypeId", "Title");

                //get list of Photographers
                viewModel.PhotographersList = repository.Find<User>(m => m.UserPermissionId == (int)AlbumUsers.Photographer).Select(m => new SelectListItem()
                {
                    Value = m.UserId.ToString(),
                    Text = m.FirstName + " " + m.LastName
                }).ToList();

                //get list of Sales Men
                viewModel.SalesMenList = repository.Find<User>(m => m.UserPermissionId == (int)AlbumUsers.SalesMan).Select(m => new SelectListItem()
                {
                    Value = m.UserId.ToString(),
                    Text = m.FirstName + " " + m.LastName,
                    Selected = (viewModel.Album.SalesManId == m.UserId)
                }).ToList();

                return View(viewModel);
            }
        }

        public ActionResult GetAlbumPrintVersions(int id)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var printVersions = repository.Find<AlbumPrintVersion>(m => m.AlbumId == id).Select(m => new AlbumPrintVersionData(m)).ToList();
                return Json(printVersions, JsonRequestBehavior.AllowGet);
            }
        }

        [HttpPost]
        public ActionResult ChangeAlbumStatus(int id, int statusId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(id);

                album.AlbumStatusId = statusId;

                //if status "מאושר על ידי מרכזת"
                if (statusId == 4)
                {
                    //change the lock status to "נעול"
                    album.AlbumLockStatusId = 1;

                    var mailTitle = "אישור מרכזת - " + album.Title;
                    var mailText = "האלבום \"" + album.Title + "\" אושר ע\"י המרכזת.";
                    var albumLoginUrl = Url.Action("EditorLogin", "Users", new { id = album.OrderNum }, "http");

                    AlbumDesigner.Helpers.MailHelper.SendMail("admin@elinirschool.co.il", mailTitle, mailText, albumLoginUrl);
                }

                repository.UnitOfWork.SaveChanges();

                return Json(new { Key = true, Value = "הסטטוס עודכן." });
            }
        }

        public ActionResult StatusMailConfirm(int AlbumId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(AlbumId);
                ViewBag.EditorEmail = album.Editor.Email;

                return PartialView();
            }
        }

        [HttpPost]
        public ActionResult UpdateAlbumDetails(AlbumData album, bool SendMail)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //get the album to be updated
                var existingAlbum = repository.GetByKey<Album>(album.AlbumId);
                var oldStatusId = existingAlbum.AlbumStatusId;

                //if the lock status is being changed from "נעול" to "פתוח"
                if (existingAlbum.AlbumLockStatusId == 1 && album.AlbumLockStatusId == 2)
                {
                    //change all sections lock status to "פתוח"
                    existingAlbum.AlbumSections.ToList().ForEach(m => m.AlbumSectionLockStatusId = 3);
                }

                //if the paperId of this album has been changed
                if (existingAlbum.PaperId != album.PaperId)
                {
                    existingAlbum.HasRender = false;
                }

                //update the album details
                existingAlbum.Title = album.Title;
                existingAlbum.NumOfCopies = album.NumOfCopies;
                existingAlbum.OrderNum = album.OrderNum;
                existingAlbum.PaperId = album.PaperId;
                existingAlbum.DueDate = DateTime.Parse(album.DueDate);
                existingAlbum.IsOneSided = album.IsOneSided;
                existingAlbum.HasPhotographer = album.HasPhotographer;
                existingAlbum.IncludeGraphics = album.IncludeGraphics;
                existingAlbum.IntroPagesNumber = album.IntroPagesNumber;
                existingAlbum.SalesManId = album.SalesManId;
                existingAlbum.AlbumStatusId = album.AlbumStatusId;
                existingAlbum.AlbumLockStatusId = album.AlbumLockStatusId;
                existingAlbum.NumOfPages = album.NumOfPages;

                repository.UnitOfWork.SaveChanges();

                if (SendMail)
                {
                    //send mail to notify the album editor
                    SendMailForAlbumStatusChange(oldStatusId, existingAlbum);

                    return Json(new { Key = true, Value = "פרטי האלבום עודכנו ונשלח מייל לעורך." });
                }

                return Json(new { Key = true, Value = "פרטי האלבום עודכנו." });
            }
        }

        [HttpPost]
        public ActionResult UpdateAlbumEditorDetails(AlbumData Album)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //get the album to be updated
                var existingAlbum = repository.GetByKey<Album>(Album.AlbumId);

                // TEMP: Catch bug..
                if (String.IsNullOrEmpty(Album.EditorEmail) &&
                    !String.IsNullOrEmpty(existingAlbum.Editor.Email))
                {
                    throw new Exception("Please contact Elad");
                }

                //update the editor details
                existingAlbum.Editor.Email = Album.EditorEmail;
                existingAlbum.Editor.Password = Album.EditorPassword;
                existingAlbum.Editor.FirstName = Album.EditorFirstName;
                existingAlbum.Editor.LastName = Album.EditorLastName;
                existingAlbum.Editor.Phone = Album.EditorPhone;
                existingAlbum.Editor.Mobile = Album.EditorMobile;

                repository.UnitOfWork.SaveChanges();

                return Json(new { Key = true, Value = "פרטי עורך האלבום עודכנו." });
            }
        }

        public ActionResult SectionDetails(int id)
        {
            //redirect the user if he has no permission for this section
            if (!AlbumsLogic.canUserEdit(AlbumSectionId: id))
            {
                return View("NoPermission");
            }

            using (GenericRepository repository = new GenericRepository())
            {
                var viewModel = new AlbumSectionDetailsViewModel();

                //get the specified AlbumSection
                var albumSection = repository.GetByKey<AlbumSection>(id);
                viewModel.AlbumSection = new AlbumSectionData(albumSection);
                viewModel.Album = new AlbumData(albumSection.Album);

                return View(viewModel);
            }
        }

        [HttpPost]
        public ActionResult UpdateAlbumSectionEditorDetails(AlbumSectionData albumSection)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //get the albumSection to be updated
                var existingAlbumSection = repository.GetByKey<AlbumSection>(albumSection.AlbumSectionId);

                //update the editor details
                existingAlbumSection.Editor.Email = albumSection.EditorEmail;
                existingAlbumSection.Editor.Password = albumSection.EditorPassword;
                existingAlbumSection.Editor.FirstName = albumSection.EditorFirstName;
                existingAlbumSection.Editor.LastName = albumSection.EditorLastName;
                existingAlbumSection.Editor.Phone = albumSection.EditorPhone;
                existingAlbumSection.Editor.Mobile = albumSection.EditorMobile;

                repository.UnitOfWork.SaveChanges();

                return Json(new { Key = true, Value = "פרטי עורך המקטע עודכנו." });
            }
        }

        [HttpPost]
        public ActionResult ChangeAlbumSectionStatus(int id, int statusId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var albumSection = repository.GetByKey<AlbumSection>(id);

                albumSection.AlbumSectionStatusId = statusId;

                //if the new status is "מאושר על ידי תלמיד"
                if (statusId == 2)
                {
                    //the lock is "נעול מרכזת"
                    albumSection.AlbumSectionLockStatusId = 2;

                    var albumEditor = albumSection.Album.Editor;
                    if (albumEditor != null)
                    {
                        //send mail to the album editor
                        var mailTitle = "אישור מקטע - " + albumSection.Title;
                        var mailText = "המקטע \"" + albumSection.Title + "\" באלבום \"" + albumSection.Album.Title + "\" אושר ע\"י עורך המקטע.";
                        var albumLoginUrl = Url.Action("EditorLogin", "Users", new { id = albumSection.Album.OrderNum }, "http");

                        AlbumDesigner.Helpers.MailHelper.SendMail(albumEditor.Email, mailTitle, mailText, albumLoginUrl);
                    }
                }
                //if the new status is "פתוח לעריכה"
                else if (statusId == 1)
                {
                    //send mail to the album section editor
                    var mailTitle = "פתיחת מקטע - " + albumSection.Title;
                    var mailText = "המקטע \"" + albumSection.Title + "\" באלבום \"" + albumSection.Album.Title + "\" נפתח לעריכה ע\"י עורך המקטע.";
                    var albumLoginUrl = Url.Action("EditorLogin", "Users", new { id = albumSection.Album.OrderNum }, "http");

                    AlbumDesigner.Helpers.MailHelper.SendMail(albumSection.Editor.Email, mailTitle, mailText, albumLoginUrl);
                }

                repository.UnitOfWork.SaveChanges();

                return Json(new { Key = true, Value = "הסטטוס עודכן." });
            }
        }

        [HttpPost]
        public ActionResult ChangeAlbumSectionLockStatus(int id, int lockStatusId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var albumSection = repository.GetByKey<AlbumSection>(id);

                albumSection.AlbumSectionLockStatusId = lockStatusId;
                repository.UnitOfWork.SaveChanges();

                return Json(new { Key = true, Value = "מצב הנעילה עודכן." });
            }
        }

        public ActionResult AlbumEditorView(int id) // "id" parameter is the Order Number
        {
            JavaScriptSerializer jsSerializer = new JavaScriptSerializer();

            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.Find<Album>(m => m.OrderNum == id).FirstOrDefault();

                //redirect the user if he has no permission for this album
                if (!AlbumsLogic.canUserEdit(album.AlbumId))
                {
                    return RedirectToAction("EditorLogin", "Users", new { id = id });
                }

                var viewModel = new AlbumDetailsViewModel();
                viewModel.Album = new AlbumData(album);

                //get the availiable AlbumSections statuses for the album editor
                var albumSectionsStatuses = repository.GetAll<AlbumSectionStatus>().ToList();
                viewModel.AlbumSectionStatusesList = new SelectList(albumSectionsStatuses, "AlbumSectionStatusId", "Title");

                //get the availiable AlbumSections LockStatuses for the album editor
                var albumSectionsLockStatuses = repository.GetAll<AlbumSectionLockStatus>().ToList();
                viewModel.AlbumSectionLockStatusesList = new SelectList(albumSectionsLockStatuses, "AlbumSectionLockStatusId", "Title");

                //serialize the FilmingDays list to JSON
                var filmingDays = repository.Find<FilmingDay>(m => m.Album.OrderNum == id).Select(m => new FilmingDayData(m)).ToList();
                viewModel.FilmingDaysJSON = jsSerializer.Serialize(filmingDays);

                //get the print versions that are checked as "Show to Album Editor"
                var printVersions = album.AlbumPrintVersions.Where(m => m.ShowToAlbumEditor).OrderBy(m => m.VersionIdx).ToList();
                viewModel.PrintVersions = printVersions.Select(m => new AlbumPrintVersionData(m)).ToList();

                return View(viewModel);
            }
        }

        public ActionResult AlbumSectionEditorView(int id, int album) // "album" parameter is the OrderNumber
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var viewModel = new AlbumSectionDetailsViewModel();

                //get the specified AlbumSection
                var albumSection = repository.Find<AlbumSection>(m => m.AlbumSectionId == id && m.Album.OrderNum == album).FirstOrDefault();
                viewModel.AlbumSection = new AlbumSectionData(albumSection);
                viewModel.Album = new AlbumData(albumSection.Album);

                //redirect the user if he has no permission for this section
                if (!AlbumsLogic.canUserEdit(AlbumSectionId: viewModel.AlbumSection.AlbumSectionId))
                {
                    return RedirectToAction("EditorLogin", "Users", new { id = albumSection.Album.OrderNum });
                }

                return View(viewModel);
            }
        }

        public ActionResult EditSectionEditors(int id) // "id" parameter is the Order Number
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var viewModel = new EditSectionEditorsViewModel();

                var album = repository.Find<Album>(m => m.OrderNum == id).FirstOrDefault();
                viewModel.OrderNum = album.OrderNum;
                viewModel.AlbumTitle = album.Title;

                //get the AlbumSections list
                var albumSections = repository.Find<AlbumSection>(m => m.Album.OrderNum == id).Select(m => new AlbumSectionData(m)).ToList();
                viewModel.Sections = albumSections;

                return PartialView(viewModel);
            }
        }

        [HttpPost]
        public ActionResult UpdateAlbumSections(int id, List<AlbumSectionData> sections)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(id);

                //loop through all the sections sent in form
                foreach (var section in sections)
                {
                    //if this is a Section that has been exist in DB (has Id)
                    if (section.AlbumSectionId > 0)
                    {
                        var existingSection = repository.GetByKey<AlbumSection>(section.AlbumSectionId);
                        var oldStatusId = existingSection.AlbumSectionStatusId;

                        existingSection.Title = section.SectionTitle;
                        existingSection.AlbumSectionTypeId = section.AlbumSectionTypeId;
                        existingSection.AlbumSectionStatusId = section.AlbumSectionStatusId;
                        existingSection.AlbumSectionLockStatusId = section.AlbumSectionLockStatusId;
                        existingSection.Editor.Password = section.EditorPassword;
                        existingSection.Editor.Email = section.EditorEmail;
                        existingSection.Editor.FirstName = section.EditorFirstName;
                        existingSection.Editor.LastName = section.EditorLastName;
                        existingSection.Editor.Phone = section.EditorPhone;
                        existingSection.Editor.Mobile = section.EditorMobile;

                        //if the page count has been increased
                        if (section.PagesCount > existingSection.PagesCount)
                        {
                            var doublePagesToAdd = (section.PagesCount - existingSection.PagesCount) / 2;

                            //find the Index of the last page (the new pages will be added before it)
                            var lastPage = existingSection.AlbumPages.OrderBy(m => m.SectionPageIdx).LastOrDefault();
                            if (lastPage != null)
                            {
                                var lastPageIdx = lastPage.SectionPageIdx;

                                for (int j = 0; j < doublePagesToAdd; j++)
                                {
                                    //create double AlbumPage for this AlbumSection
                                    var albumPage = new AlbumPage();
                                    albumPage.SectionPageIdx = lastPageIdx;
                                    albumPage.IsSingle = false;
                                    existingSection.AlbumPages.Add(albumPage);

                                    lastPageIdx++;
                                }

                                lastPage.SectionPageIdx = lastPageIdx;
                            }
                        }
                        //if the page count has been decreased
                        else if (section.PagesCount < existingSection.PagesCount)
                        {
                            var doublePagesToDelete = (existingSection.PagesCount - section.PagesCount) / 2;

                            //find the Index of the last page (the pages before this page - will be deleted)
                            var lastPage = existingSection.AlbumPages.OrderBy(m => m.SectionPageIdx).LastOrDefault();
                            if (lastPage != null)
                            {
                                var lastPageIdx = lastPage.SectionPageIdx;

                                //get all the pages double that should be removed (x pages before the last one)
                                var pagesToDelete = existingSection.AlbumPages.Where(m => m.SectionPageIdx < lastPageIdx && m.IsSingle == false).OrderByDescending(m => m.SectionPageIdx).Take(doublePagesToDelete).ToList();

                                pagesToDelete.ForEach(m => repository.Delete<AlbumPage>(m));

                                lastPage.SectionPageIdx = lastPageIdx - pagesToDelete.Count;
                            }

                            //set "HasRender" field of this Album to false (to allow PDF re-rendering)
                            album.HasRender = false;
                        }

                        existingSection.PagesCount = section.PagesCount;

                        repository.UnitOfWork.SaveChanges();

                        //send mail to notify the section editor
                        SendMailForAlbumSectionStatusChange(oldStatusId, existingSection);
                    }
                    //if this is new Section
                    else
                    {
                        var newSectionIndex = album.AlbumSections.Max(m => m.SectionIdx) + 1;

                        //check that the pages number is valid (equal or great than 2, and even number)
                        if (section.PagesCount >= 2 && section.PagesCount % 2 == 0)
                        {
                            //create and insert new AlbumSection
                            var newSection = CreateNewAlbumSection(album.Title, section, newSectionIndex);

                            album.AlbumSections.Add(newSection);
                            repository.UnitOfWork.SaveChanges();

                            section.AlbumSectionId = newSection.AlbumSectionId;
                        }
                    }

                    repository.UnitOfWork.SaveChanges();
                }

                //find sections that are not anymore in the Sections collection - remove them
                var deletedSections = album.AlbumSections.Where(m => sections.Any(n => n.AlbumSectionId == m.AlbumSectionId) == false).ToList();

                if (deletedSections.Count > 0)
                {
                    //delete the images of each deleted section
                    deletedSections.ForEach(m => repository.Delete<DesignImage>(n => n is AlbumImage && (n as AlbumImage).AlbumSectionId == m.AlbumSectionId));
                    deletedSections.ForEach(m => repository.Delete<AlbumSection>(m));

                    //set "HasRender" field of this Album to false (to allow PDF re-rendering)
                    album.HasRender = false;

                    repository.UnitOfWork.SaveChanges();
                }

                return Json(new { Key = true, Value = "המקטעים עודכנו." });
            }
        }

        [HttpPost]
        public ActionResult UpdateFilmingDays(int id, List<FilmingDay> filmingDays)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //delete all the existing FilmingDays of this Album
                var album = repository.GetByKey<Album>(id);
                album.FilmingDays.ToList().ForEach(m => repository.Delete<FilmingDay>(m));

                if (filmingDays != null)
                {
                    //loop through the FilmingDays and insert them
                    foreach (var filmingDay in filmingDays)
                    {
                        filmingDay.AlbumId = id;
                        album.FilmingDays.Add(filmingDay);
                    }
                }

                repository.UnitOfWork.SaveChanges();

                return Json(new { Key = true, Value = "ימי הצילום עודכנו." });
            }
        }

        [HttpPost]
        public ActionResult UpdatePrintVersions(int id, List<AlbumPrintVersion> printVersions)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                if (printVersions != null)
                {
                    //loop through the PrintVersions and update
                    foreach (var printVersion in printVersions)
                    {
                        var existingPrintVersion = repository.GetByKey<AlbumPrintVersion>(printVersion.AlbumPrintVersionId);
                        existingPrintVersion.AlbumPrintVersionStatusId = printVersion.AlbumPrintVersionStatusId;
                        existingPrintVersion.PdfSentDate = printVersion.PdfSentDate;
                        existingPrintVersion.PrintSentDate = printVersion.PrintSentDate;
                        existingPrintVersion.ShowToAlbumEditor = printVersion.ShowToAlbumEditor;
                    }
                }
                else
                {
                    printVersions = new List<AlbumPrintVersion>();
                }

                repository.UnitOfWork.SaveChanges();


                // Remove Print Versions according to user's input
                var albumPrintVersions = repository.Find<AlbumPrintVersion>(m => m.AlbumId == id);
                var deletedPrintVersions = albumPrintVersions.Where(m => printVersions.Any(n => n.AlbumPrintVersionId == m.AlbumPrintVersionId) == false).ToList();

                // Delete Print Version Files and Entity
                if (deletedPrintVersions.Count > 0)
                {
                    foreach (var pv in deletedPrintVersions)
                    {
                        AlbumPrintVersionHelper.RemovePrintVersion(pv.AlbumPrintVersionId);
                    }
                }

                return Json(new { Key = true, Value = "גרסאות הדפוס עודכנו." });
            }
        }

        [HttpPost]
        public ActionResult UpdateStudioNotes(int id, string studioNotes)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //get the album to be updated
                var existingAlbum = repository.GetByKey<Album>(id);

                //update the studio notes
                existingAlbum.StudioNotes = studioNotes;

                repository.UnitOfWork.SaveChanges();

                return Json(new { Key = true, Value = "הערות הסטודיו עודכנו." });
            }
        }

        public ActionResult ShowApprovalChecks(bool isSection)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var approvalCheckes = repository.Find<ApprovalCheck>(m => m.IsSection == isSection).ToList();

                return PartialView(approvalCheckes);
            }
        }

        /* Album Render proccess
         ------------------------*/

        [HttpPost]
        public ActionResult Render(int id, int quality)
        {
            //redirect the user if he has no permission for this album
            if (!AlbumsLogic.canUserEdit(id))
            {
                return View("NoPermission");
            }

            using (GenericRepository repository = new GenericRepository())
            {
                var existingRender = repository.Find<RenderTask>(m => m.AlbumId == id).FirstOrDefault();

                //check that there is no render task for this album
                if (existingRender == null)
                {
                    //add new RenderTask
                    var renderTask = new RenderTask() { AlbumId = id, Quality = quality };
                    repository.Add<RenderTask>(renderTask);

                    repository.UnitOfWork.SaveChanges();
                }
            }

            return PartialView();
        }

        [HttpPost]
        public ActionResult GetRenderDialog(int id)
        {
            return PartialView("Render");
        }
        

        [HttpPost]
        public ActionResult GetRenderStatus(int id)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(id);

                var albumPages = album.AlbumSections.Sum(m => m.AlbumPages.Count);

                //count the number of renedered pages in this album's sections
                var renderedPagesCount = 0;
                album.AlbumSections.ToList().ForEach(m => renderedPagesCount += m.AlbumPages.Where(n => n.HasRender).Count());

                return Json(new { AlbumPages = albumPages, RenderedPagesCount = renderedPagesCount });
            }
        }

        /*-----------------------*/

        [HttpPost]
        public ActionResult GetPdfStatus(int id)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var renderTask = repository.Find<RenderTask>(m => m.AlbumId == id).FirstOrDefault();
                if (renderTask != null)
                {
                    //get the completed percentage of this PDF render task
                    var TotalPagesCount = repository.Find<AlbumPage>(m => m.AlbumSection.AlbumId == id).Count();
                    var percentage = ((double)renderTask.RenderedPages / (double)TotalPagesCount) * 100;

                    if (percentage < 100)
                    {
                        return Json(new
                        {
                            Percentage = percentage,
                            Message = ""
                        });
                    }
                }

                //get the links to download the PDF files
                var latestAlbumPrintVersion = repository.Find<AlbumPrintVersion>(m => m.AlbumId == id).OrderByDescending(m => m.VersionIdx).FirstOrDefault();
                var innerFileDownload = Url.Action("DownloadFile", "Pdf", new { url = latestAlbumPrintVersion.InnerUrl });
                var coverFileDownload = Url.Action("DownloadFile", "Pdf", new { url = latestAlbumPrintVersion.CoverUrl });

                //completed
                return Json(new
                {
                    Percentage = 100,
                    Message = "הפקת גרסת ההדפסה הושלמה בהצלחה!<br /><a href='" + innerFileDownload + "'>הורד PDF אלבום</a> | <a href='" + coverFileDownload + "'>הורד PDF כריכה</a>"
                });
            }
        }

        public ActionResult SetPdfQuality()
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var viewModel = new SettingsViewModel();

                //get the image render quality
                var renderVariables = repository.GetAll<RenderVariable>().FirstOrDefault();
                viewModel.Quality = renderVariables.Quality;

                return PartialView(viewModel);
            }
        }

        

        public ActionResult EditorsFile(int id)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(id);

                if (!AlbumsLogic.canUserEdit(id))
                {
                    return View("NoPermission");
                }

                string validTitle = FilesHelper.MakeValidFileName(album.Title);

                //create a new html file
                var fileUrl = Server.MapPath("~/Editors-" + validTitle + ".html");
                var sw = System.IO.File.CreateText(fileUrl);
                var editorLoginUrl = Url.Action("EditorLogin", "Users", new { id = album.OrderNum }, "http");

                sw.Write("<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body style='direction:rtl;font-family:Arial;'>");
                sw.Write("<h1>סיסמאות עריכה - " + album.Title + "</h1>");
                sw.Write("עמוד כניסת עורך: <a href='" + editorLoginUrl + "'>" + editorLoginUrl + "</a><br />");
                sw.Write("סיסמת עורך האלבום: " + album.Editor.Password);
                sw.Write("<br /><br />");

                var editorsTable = AlbumHelper.EditorsPasswordsTable(album);
                sw.Write(editorsTable);

                sw.Write("</body></html>");
                sw.Close();

                var str = System.IO.File.ReadAllText(fileUrl);
                System.IO.File.Delete(fileUrl);

                System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
                Byte[] BytesMessage = UTF8.GetBytes(str);

                return File(BytesMessage, "text/html", Path.GetFileName(fileUrl));
            }
        }

        [HttpPost]
        public ActionResult SectionsOfAlbum(int id)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //get the sections of the specified album
                var sectionsList = repository.Find<AlbumSection>(m => m.AlbumId == id);
                var sections = sectionsList.Select(m => new AlbumSectionData(m)).ToList();

                return Json(sections);
            }
        }

        [HttpPost]
        public ActionResult GetContractPDF(int id)
        {
            var contractPath = "";
            var contractDir = Server.MapPath("~/resources/albums/" + id + "/contract");

            if (Directory.Exists(contractDir))
            {
                //search contract files with this album id
                var files = Directory.GetFiles(contractDir);

                if (files.Length > 0)
                {
                    contractPath = Url.Content("~/resources/albums/" + id + "/contract/" + Path.GetFileName(files[0]));
                }
            }

            return Json(contractPath);
        }

        [HttpPost]
        public ActionResult UploadContractPDF(int id, HttpPostedFileBase ContractPdfFile)
        {
            var contractDir = Server.MapPath("~/resources/albums/" + id + "/contract");
            if (!Directory.Exists(contractDir))
            {
                Directory.CreateDirectory(contractDir);
            }

            //delete the existing file (if there is one)
            var existingFile = Directory.GetFiles(contractDir);
            if (existingFile.Length > 0)
            {
                System.IO.File.Delete(existingFile[0]);
            }

            //upload the contract file
            var filePath = Server.MapPath("~/resources/albums/" + id + "/contract/" + id + Path.GetExtension(ContractPdfFile.FileName));
            ContractPdfFile.SaveAs(filePath);

            return RedirectToAction("Details", new { id = id });
        }

        [HttpPost]
        public ActionResult UploadApprovalPDF(int id, HttpPostedFileBase ApprovalPdfFile, int AlbumId)
        {
            var approvalDir = Server.MapPath("~/resources/albums/" + AlbumId + "/approval");
            if (!Directory.Exists(approvalDir))
            {
                Directory.CreateDirectory(approvalDir);
            }

            //delete the existing file (if there is one)
            var existingFile = Directory.GetFiles(approvalDir, id + ".*");
            if (existingFile.Length > 0)
            {
                System.IO.File.Delete(existingFile[0]);
            }

            //upload the approval file
            var filePath = Server.MapPath("~/resources/albums/" + AlbumId + "/approval/" + id + Path.GetExtension(ApprovalPdfFile.FileName));
            ApprovalPdfFile.SaveAs(filePath);

            return RedirectToAction("Details", new { id = AlbumId });
        }

        public ActionResult GetRenderVariables()
        {
            using (GenericRepository repository = new GenericRepository())
            {
                bool IsRenderProccessEmpty = false;
                bool IsRenderRun = false;

                var renderVariables = repository.GetAll<RenderVariable>().FirstOrDefault();
                if (renderVariables != null)
                {
                    //check if there is no RenderTask running now
                    var runningRenderedTasks = repository.GetAll<RenderTask>().Count(m => m.Started);
                    if (runningRenderedTasks == 0)
                    {
                        IsRenderProccessEmpty = true;
                    }

                    //if the last render check occured in the last minute
                    if ((DateTime.Now - renderVariables.LastCheck).TotalMinutes < 1)
                    {
                        IsRenderRun = true;
                    }
                }

                return Json(new
                {
                    IsRenderProccessEmpty = IsRenderProccessEmpty,
                    IsRenderRun = IsRenderRun
                }, JsonRequestBehavior.AllowGet);
            }
        }

        public ActionResult SetAlbumAsRemoved(int id)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(id);
                var albumData = new AlbumData(album);

                ViewBag.AlbumTitle = album.Title;
                ViewBag.DirectorySize = albumData.DirectorySize;

                return PartialView();
            }
        }

        [HttpPost]
        public ActionResult SetAlbumAsRemoved(int id, bool DeleteFiles)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(id);

                //set this Album as Removed
                album.IsRemoved = true;
                repository.UnitOfWork.SaveChanges();

                if (DeleteFiles)
                {
                    //delete the album files
                    var albumDir = Server.MapPath("~/resources/albums/" + id);
                    if (Directory.Exists(albumDir))
                    {
                        Directory.Delete(albumDir, true);
                    }
                }

                return Json(true);
            }
        }

        public ActionResult MailMsgDialog()
        {
            return PartialView();
        }

        public ActionResult AlbumFiles(int AlbumId)
        {
            //redirect the user if he has no permission for this album
            if (!AlbumsLogic.canUserEdit(AlbumId))
            {
                return Json(false);
            }

            var albumDir = Server.MapPath("~/resources/albums/" + AlbumId + "/");

            var viewModel = new AlbumFilesViewModel();
            viewModel.AlbumId = AlbumId;

            //get the directories size and files count
            var albumImagesSize = FilesHelper.GetDirectorySize(albumDir + "images");
            var albumSectionImagesSize = FilesHelper.GetDirectorySize(albumDir + "sectionImages");
            viewModel.AlbumImagesSize = FilesHelper.BytesToMegaBytes(albumImagesSize + albumSectionImagesSize);

            var albumImagesCount = FilesHelper.GetDirectoryFilesCount(albumDir + "images");
            var albumSectionImagesCount = FilesHelper.GetDirectoryFilesCount(albumDir + "sectionImages");
            viewModel.AlbumImagesCount = albumImagesCount + albumSectionImagesCount;

            var pagesSize = FilesHelper.GetDirectorySize(albumDir + "pages");
            viewModel.PagesSize = FilesHelper.BytesToMegaBytes(pagesSize);
            viewModel.PagesCount = FilesHelper.GetDirectoryFilesCount(albumDir + "pages");

            var pdfSize = FilesHelper.GetDirectorySize(albumDir + "pdf");
            viewModel.PdfSize = FilesHelper.BytesToMegaBytes(pdfSize);
            viewModel.PdfCount = FilesHelper.GetDirectoryFilesCount(albumDir + "pdf");

            var layoutsSize = FilesHelper.GetDirectorySize(albumDir + "layouts");
            viewModel.LayoutsSize = FilesHelper.BytesToMegaBytes(layoutsSize);
            viewModel.LayoutsCount = FilesHelper.GetDirectoryFilesCount(albumDir + "layouts");

            var contractSize = FilesHelper.GetDirectorySize(albumDir + "contract");
            viewModel.ContractSize = FilesHelper.BytesToMegaBytes(contractSize);
            viewModel.ContractCount = FilesHelper.GetDirectoryFilesCount(albumDir + "contract");

            var approvalSize = FilesHelper.GetDirectorySize(albumDir + "approval");
            viewModel.ApprovalSize = FilesHelper.BytesToMegaBytes(approvalSize);
            viewModel.ApprovalCount = FilesHelper.GetDirectoryFilesCount(albumDir + "approval");

            /*long removedAlbumImagesSize = 0;
            using (var db = new AlbumContext())
            {
                //loop through the album images that have been removed
                var removedImages = db.AlbumImages.Where(m => m.AlbumId == AlbumId && m.IsRemoved).ToList();
                foreach (var image in removedImages)
                {
                    removedAlbumImagesSize += AlbumHelper.GetAlbumImageFilesSize(image);
                }
            }
            viewModel.RemovedAlbumImagesSize = FilesHelper.BytesToMegaBytes(removedAlbumImagesSize);*/

            return PartialView(viewModel);
        }

        public ActionResult DeleteAlbumFiles(int AlbumId)
        {
            using (var db = new AlbumContext())
            {
                var album = db.Albums.Find(AlbumId);
                ViewBag.AlbumTitle = album.Title;

                return PartialView();
            }
        }

        [HttpPost]
        public ActionResult DeleteAlbumFiles(int AlbumId, bool Delete)
        {
            var albumDir = Server.MapPath("~/resources/albums/" + AlbumId + "/");

            //delete all the files in the directories of this album
            var deleteDir = albumDir + "images";
            if (Directory.Exists(deleteDir))
            {
                Directory.Delete(deleteDir, true);
            }
            deleteDir = albumDir + "sectionImages";
            if (Directory.Exists(deleteDir))
            {
                Directory.Delete(deleteDir, true);
            }
            deleteDir = albumDir + "pages";
            if (Directory.Exists(deleteDir))
            {
                Directory.Delete(deleteDir, true);
            }
            deleteDir = albumDir + "layouts";
            if (Directory.Exists(deleteDir))
            {
                Directory.Delete(deleteDir, true);
            }
            deleteDir = albumDir + "contract";
            if (Directory.Exists(deleteDir))
            {
                Directory.Delete(deleteDir, true);
            }
            deleteDir = albumDir + "approval";
            if (Directory.Exists(deleteDir))
            {
                Directory.Delete(deleteDir, true);
            }

            using (var db = new AlbumContext())
            {
                //get the print versions of this Album (except of the last one)
                var printVersions = (from p in db.AlbumPrintVersions
                                     where p.AlbumId == AlbumId
                                     orderby p.VersionDate descending
                                     select p).Skip(1);

                foreach (var printVersion in printVersions)
                {
                    //Delete print version files
                    var innerFile = Server.MapPath("~/" + printVersion.InnerUrl);
                    var coverFile = Server.MapPath("~/" + printVersion.CoverUrl);
                    System.IO.File.Delete(innerFile);
                    System.IO.File.Delete(coverFile);
                }
            }

            return Json(true);
        }

        public ActionResult ApprovalFile(int AlbumPrintVersionId)
        {
            using (var db = new AlbumContext())
            {
                var albumPrintVersion = db.AlbumPrintVersions.Find(AlbumPrintVersionId);

                ViewBag.AlbumId = albumPrintVersion.AlbumId;
                ViewBag.AlbumPrintVersionId = AlbumPrintVersionId;
                ViewBag.VersionIdx = albumPrintVersion.VersionIdx;

                var approvalDir = "~/resources/albums/" + albumPrintVersion.AlbumId + "/approval";
                if (Directory.Exists(Server.MapPath(approvalDir)))
                {
                    //search approval files with this album id
                    var files = Directory.GetFiles(Server.MapPath(approvalDir), AlbumPrintVersionId + ".*");
                    if (files.Length > 0)
                    {
                        ViewBag.ApprovalFilePath = Url.Content(approvalDir + "/" + Path.GetFileName(files[0]));
                    }
                }

                return PartialView();
            }
        }

        public ActionResult CalculateSpineWidth(int AlbumId, int PaperId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(AlbumId);
                var paper = repository.GetByKey<Paper>(PaperId);

                // calculate the actual spine width according to pages number * paper thickness
                var spineWidthMm = AlbumHelper.CalculateSpineWidthMm(album, paper);

                return Json(spineWidthMm, JsonRequestBehavior.AllowGet);
            }
        }

        [HttpPost]
        public ActionResult SendMailToAlbumEditor(int AlbumId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var album = repository.GetByKey<Album>(AlbumId);

                //send mail to the Album Editor
                var mailTitle = "סיסמאות עריכת אלבום - " + album.Title;
                var mailText = "פתיחת האלבום \"" + album.Title + "\" הושלמה בהצלחה.<br />אתה מוזמן להתחבר ולערוך את האלבום.<br /><h2>סיסמאות עריכה</h2><strong>סיסמת עורך האלבום</strong>: " + album.Editor.Password;
                mailText += AlbumHelper.EditorsPasswordsTable(album);
                var albumLoginUrl = Url.Action("EditorLogin", "Users", new { id = album.OrderNum }, "http");

                if (!string.IsNullOrEmpty(album.Editor.Email))
                {
                    try
                    {
                        AlbumDesigner.Helpers.MailHelper.SendMail(album.Editor.Email, mailTitle, mailText, albumLoginUrl);
                    }
                    catch
                    {
                        return Json(new { Key = false, Value = "שליחת המייל נכשלה." });
                    }
                }
                else
                {
                    return Json(new { Key = false, Value = "אין כתובת דוא\"ל לעורך האלבום." });
                }

                return Json(new { Key = true, Value = "המייל נשלח בהצלחה." });
            }
        }

        [HttpPost]
        public ActionResult SendMailToAlbumSectionEditor(int AlbumSectionId)
        {
            return Json(AlbumDesigner.Helpers.MailHelper.SendPasswordMailToSectionEditor(AlbumSectionId, Url));
        }

        [HttpPost]
        public ActionResult SendPasswordMailToAllSectionEditors(int AlbumId)
        {
            return Json(AlbumDesigner.Helpers.MailHelper.SendPasswordMailToAllSectionEditors(AlbumId, Url));
        }

        private void SendMailForAlbumStatusChange(int oldStatusId, Album album)
        {
            //if the status has been changed
            if (oldStatusId != album.AlbumStatusId)
            {
                //send mail to the Album Editor
                var mailTitle = "שינוי סטטוס - " + album.Title;
                var mailText = "הסטטוס של האלבום \"" + album.Title + "\" עודכן.<br />הסטטוס הנוכחי הוא: " + album.AlbumStatus.Title + ".";
                var albumLoginUrl = Url.Action("EditorLogin", "Users", new { id = album.OrderNum }, "http");

                AlbumDesigner.Helpers.MailHelper.SendMail(album.Editor.Email, mailTitle, mailText, albumLoginUrl);
            }
        }

        private void SendMailForAlbumSectionStatusChange(int oldStatusId, AlbumSection section)
        {
            //if the status has been changed
            if (oldStatusId != section.AlbumSectionStatusId)
            {
                //send mail to the Album Editor and Section Editor
                var mailTitle = "שינוי סטטוס - " + section.Album.Title + " - " + section.Title;
                var mailText = "הסטטוס של המקטע \"" + section.Title + "\" באלבום \"" + section.Album.Title + "\" עודכן.<br />הסטטוס הנוכחי הוא: " + section.AlbumSectionStatus.Title + ".";
                var albumLoginUrl = Url.Action("EditorLogin", "Users", new { id = section.Album.OrderNum }, "http");

                AlbumDesigner.Helpers.MailHelper.SendMail(section.Album.Editor.Email, mailTitle, mailText, albumLoginUrl);

                if (section.Editor != null)
                {
                    AlbumDesigner.Helpers.MailHelper.SendMail(section.Editor.Email, mailTitle, mailText, albumLoginUrl);
                }
            }
        }

        // Flex
        [HttpPost]
        public ActionResult GetAlbumDetails(int albumId, int sectionId)
        {
            return Json(AlbumsLogic.getAlbumDetails(albumId, sectionId));
        }

    }
}
